﻿using System;
using System.IO;
using System.Runtime.Serialization.Json;
using System.Text;
using System.Web.Mvc;
using System.Web.Routing;
using Xoohoo.Extensions;
using Xoohoo.Models.ViewModels;

namespace Xoohoo.Html
{
    public static class ScriptExtensions
    {
        #region RenderScriptTag

        public static void RenderScriptTag<TModel>(this HtmlHelper<TModel> htmlHelper, string path) where TModel : XoohooViewModel
        {
            htmlHelper.RenderScriptTag(path, null);
        }
        public static void RenderScriptTag<TModel>(this HtmlHelper<TModel> htmlHelper, string path, string releasePath) where TModel : XoohooViewModel
        {
            if (string.IsNullOrEmpty(path))
            {
                throw new ArgumentNullException("path");
            }

#if DEBUG
#else
            if (!string.IsNullOrEmpty(releasePath))
                path = releasePath;
#endif

            if (!(path.StartsWith("http://") || path.StartsWith("https://")))
            {
                UrlHelper urlHelper = new UrlHelper(htmlHelper.ViewContext.RequestContext);

                path = !path.StartsWith("/")
                    ? urlHelper.ScriptPath(path, htmlHelper.ViewContext)
                    : urlHelper.AppPath(path);
            }
            htmlHelper.ViewContext.Writer.Write(htmlHelper.ScriptBlock("text/javascript", path));
        }

        #endregion

        #region RenderScriptVariable

        public static void RenderScriptVariable(this HtmlHelper htmlHelper, string name, object value)
        {
            const string scriptVariableFormat = "window.{0} = {1};";
            string script;

            if (value != null)
            {
                DataContractJsonSerializer dcjs = new DataContractJsonSerializer(value.GetType());

                using (MemoryStream ms = new MemoryStream())
                {
                    dcjs.WriteObject(ms, value);

                    script = string.Format(scriptVariableFormat, name, Encoding.Default.GetString(ms.ToArray()));

                    ms.Close();
                }
            }
            else
            {
                script = string.Format(scriptVariableFormat, name, "null");
            }

            htmlHelper.ViewContext.Writer.Write(script);
        }

        #endregion

        #region ScriptBlock

        public static MvcHtmlString ScriptBlock(this HtmlHelper htmlHelper, string type, string src)
        {
            return htmlHelper.ScriptBlock(type, src, null);
        }

        public static MvcHtmlString ScriptBlock(this HtmlHelper htmlHelper, string type, string src, object htmlAttributes)
        {
            TagBuilder tagBuilder = new TagBuilder("script");

            tagBuilder.MergeAttributes(new RouteValueDictionary(htmlAttributes));
            if (!string.IsNullOrEmpty(type))
            {
                tagBuilder.MergeAttribute("type", type);
            }
            if (!string.IsNullOrEmpty(src))
            {
                tagBuilder.MergeAttribute("src", src);
            }

            return MvcHtmlString.Create(tagBuilder.ToString(TagRenderMode.Normal));
        }

        #endregion

    }
}
